package com.wanli.graalvmdemo.configuration;

import com.wanli.graalvmdemo.configuration.components.*;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.*;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.LinkedList;

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
    private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);

    @Resource
    private LoginSuccessHandler loginSuccessHandler;
    @Resource
    private LoginFailHandler loginFailHandler;
    @Resource
    private LogoutSuccessHandler logoutSuccessHandler;
    @Resource
    private UserAuthenticationManager userAuthenticationManager;
    @Resource
    private AccessDeniedHandler accessDeniedHandler;
    @Resource
    private AuthenticationEntryPoint authenticationEntryPoint;
    @Resource
    private AuthorizeConfigManager authorizeConfigManager;

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        return http
            .authorizeExchange(exchanges -> exchanges
                .pathMatchers("/auth/**", "/register", "/test", "/css/**", "/h2-console/**").permitAll()
                .anyExchange().access(authorizeConfigManager)
//                .authenticated()
            ).csrf(ServerHttpSecurity.CsrfSpec::disable)
            // 表单登录配置
            .formLogin(e -> e
                .authenticationManager(authenticationManager())
                .authenticationSuccessHandler(loginSuccessHandler) // 设置跳转 URL
                .authenticationFailureHandler(loginFailHandler)
            )
            .logout(logout -> {
                    logout.logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
                }
            )
            .exceptionHandling(spec -> spec
                    .accessDeniedHandler(accessDeniedHandler) // 配置访问拒绝处理器
                    .accessDeniedHandler((exchange, denied) -> {
                        String errorMessage = "您没有权限访问此页面";
                        String redirectUrl = "/access-denied?errorMessage=" + URLEncoder.encode(errorMessage, StandardCharsets.UTF_8);
                        exchange.getResponse().setStatusCode(HttpStatus.FOUND);
                        exchange.getResponse().getHeaders().setLocation(URI.create(redirectUrl));
                        return exchange.getResponse().setComplete();
                    }).authenticationEntryPoint(authenticationEntryPoint)
            )
            // 开启 HTTP Basic 认证（可选，适合调试和 API 请求）
//            .httpBasic(ServerHttpSecurity.HttpBasicSpec::disable)
            .build();
    }

    @Bean
    public ReactiveAuthenticationManager authenticationManager() {
        LinkedList<ReactiveAuthenticationManager> managers = new LinkedList<>();
        managers.add(userAuthenticationManager);
        return new DelegatingReactiveAuthenticationManager(managers);
    }
}
